package com.atguigu.examsystemserver.service.impl;


import com.atguigu.examsystemserver.entity.ExamRecord;
import com.atguigu.examsystemserver.entity.Paper;
import com.atguigu.examsystemserver.entity.PaperQuestion;
import com.atguigu.examsystemserver.entity.Question;
import com.atguigu.examsystemserver.exception.ExamException;
import com.atguigu.examsystemserver.mapper.ExamRecordMapper;
import com.atguigu.examsystemserver.mapper.PaperMapper;
import com.atguigu.examsystemserver.mapper.PaperQuestionMapper;
import com.atguigu.examsystemserver.mapper.QuestionMapper;
import com.atguigu.examsystemserver.service.PaperQuestionService;
import com.atguigu.examsystemserver.service.PaperService;

import com.atguigu.examsystemserver.vo.PaperVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 试卷服务实现类
 */
@Slf4j
@Service
@Transactional
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {
    @Autowired
    PaperQuestionMapper paperQuestionMapper;
    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    PaperQuestionService paperQuestionService;
    @Autowired
    ExamRecordMapper examRecordMapper;

    @Override
    public Paper getPapersById(Integer id) {
        Paper paper = baseMapper.selectById(id);
        /*List<PaperQuestion> paperQuestions = paperQuestionMapper.selectList(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getQuestionId, id));
        List<Long> questionIds = paperQuestions.stream().map(PaperQuestion::getQuestionId).collect(Collectors.toList());
        ArrayList<Question> questions = new ArrayList<>();
        questionIds.forEach(questionid->{
            Question questionByIdCondition = questionMapper.getQuestionByIdCondition(questionid);
            questions.add(questionByIdCondition);
        });*/
        List<Question> questions = questionMapper.getQuestionListByPaperId(id);
        questions.sort(Comparator.comparing(Question::getType));
        paper.setQuestions(questions);
        return paper;
    }

    @Override
    public Paper createPaper(PaperVo paperVo) {
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, paperVo.getName()));
        if (exists) {
            throw new ExamException(949, "已存在试卷，请重新命名");
        }
        Paper paper = new Paper();
        BeanUtils.copyProperties(paperVo, paper);
        paper.setStatus("DRAFT");
        Map<Long, BigDecimal> questions = paperVo.getQuestions();
        paper.setQuestionCount(questions.size());
        BigDecimal totalScore = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(totalScore);
        baseMapper.insert(paper);
        //把Map<Long,BigDecimal> question 转为list<PaperQuestion>
        List<PaperQuestion> paperQuestions = questions.entrySet().stream().map(entry ->
                        new PaperQuestion(paper.getId(),
                                entry.getKey(),
                                entry.getValue()))
                .collect(Collectors.toList());
        paperQuestionService.saveBatch(paperQuestions);
        return paper;
    }

    @Override
    public Paper updatePaper(Integer id, PaperVo paperVo) {
        Paper paper = baseMapper.selectById(id);
        if ("PUBLISHED".equals(paper.getStatus())) {
            throw new ExamException(969, "该试卷处于发布状态，不能被修改");
        }
        BeanUtils.copyProperties(paperVo, paper);
        paper.setUpdateTime(new Date());
        Map<Long, BigDecimal> questions = paperVo.getQuestions();
        paper.setQuestionCount(questions.size());
        BigDecimal totalScore = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(totalScore);
        baseMapper.updateById(paper);

        paperQuestionMapper.delete(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId, id));
        List<PaperQuestion> paperQuestions = questions.entrySet().stream().map(entry ->
                        new PaperQuestion(paper.getId(),
                                entry.getKey(),
                                entry.getValue()))
                .collect(Collectors.toList());
        paperQuestionService.saveBatch(paperQuestions);
        return paper;
    }

    @Override
    public void updatePaperStatus(Integer id, String status) {
        Long count = examRecordMapper.selectCount(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getExamId, id));
        if (count > 0) {
            throw new ExamException(979, "试卷正在被考试，不能修改");
        }
        baseMapper.update(null,new LambdaUpdateWrapper<Paper>().eq(Paper::getId,id).set(Paper::getStatus,status));
    }

    @Override
    public void removePaper(Integer id) {
        Long count = examRecordMapper.selectCount(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getExamId, id));
        if (count>0){
            throw new ExamException(989,"试卷正在被考试，不能被修改");
        }
        paperQuestionMapper.delete(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId,id));
    }
}